/**
 * PWM Module
 * Features:
 * - Supports PWM Operate
 * 
 * Usage:
 * - Simple Pwm Control
 */
import { pwmClass } from './libvbar-b-dxpwm.so'
import * as os from "os"

let pwmObj = new pwmClass();
const pwm = {}

/**
 * Initialize PWM object
 * @returns object
 */
pwm.init = function (channel = 0) {
	return pwmObj.init(channel)
}

/**
 * Release and clean the designated PWM channel
 * @param {number} channel The PWM channel number to use
 * @returns true/false
 */
pwm.deinit = function (channel = 0) {
	if (channel === null || channel === undefined || channel === "" || isNaN(channel)) {
		throw new Error("channel is required");
	}
	return pwmObj.deinit(channel)
}

/**
 * Set the power of the channel
 * @param {number} power  Power range of 0-100
 * @param {number} channel  The PWM channel number to use
 * @returns true/false
 */
pwm.setPower = function (power, channel = 0) {
	if (power === null || power === undefined || power === "" || isNaN(power)) {
		throw new Error("power is required");
	}
	if (channel === null || channel === undefined || channel === "" || isNaN(channel)) {
		throw new Error("channel is required");
	}
	return pwmObj.setPower(power, channel)
}

/**
* Generates a non-blocking beep sound. Note: pwm.init() must be called for the channel before using this function.
* This function returns immediately and performs beeping in the background.
* @param {object} options Parameters for beeping. Optional.
* 		@param {number} options.count       Number of beeps. Defaults to 1.
* 		@param {number} options.time        Duration of each beep in milliseconds. Defaults to 50.
* 		@param {number} options.interval    Interval between beeps in milliseconds. Defaults to 50.
* 		@param {number} options.volume      Beep volume (0-100). Defaults to 50.
* @param {number} channel The PWM channel to use. Defaults to 0.
*/
pwm.beep = function (options = {}, channel = 0) {
	const {
		count = 1,
		time = 50,
		interval = 50,
		volume = 50,
	} = options;

	for (let i = 0; i < count; i++) {
		pwm.setPower(volume, channel)
		os.sleep(time)
		pwm.setPower(0, channel)
		if (i < (count - 1)) {
			// The last beep was without interruption
			os.sleep(interval)
		}
	}
}

/**
 * Plays a short beep, typically for a key press.
 * @param {number} volume Beep volume (0-100). Defaults to 50.
 * @param {number} channel The PWM channel to use. Defaults to 0.
 */
pwm.pressBeep = function (volume = 50, channel = 0) {
	pwm.beep({ time: 30, count: 1, volume: volume }, channel);
}

/**
 * Plays a long beep, typically to indicate failure.
 * @param {number} volume Beep volume (0-100). Defaults to 50.
 * @param {number} channel The PWM channel to use. Defaults to 0.
 */
pwm.failBeep = function (volume = 50, channel = 0) {
	pwm.beep({ time: 500, count: 1, volume: volume }, channel);
}

/**
 * Plays two short beeps, typically to indicate success.
 * @param {number} volume Beep volume (0-100). Defaults to 50.
 * @param {number} channel The PWM channel to use. Defaults to 0.
 */
pwm.successBeep = function (volume = 50, channel = 0) {
	pwm.beep({ time: 30, count: 2, volume: volume }, channel);
}

/**
 * Plays a standard beep, typically as a warning.
 * @param {number} volume Beep volume (0-100). Defaults to 50.
 * @param {number} channel The PWM channel to use. Defaults to 0.
 */
pwm.warningBeep = function (volume = 50, channel = 0) {
	pwm.beep({ count: 1, volume: volume }, channel);
}

export default pwm;
